package com.wxtools.api;

import com.wxtools.bean.MiniJsCode2SessionResult;
import com.wxtools.bean.WxUserList;
import com.wxtools.bean.result.WxError;
import com.wxtools.bean.result.WxOAuth2AccessTokenResult;
import com.wxtools.exception.WxErrorException;
import com.wxtools.util.http.RequestExecutor;

import java.util.Map;

public interface IMiniService {

    /**
     * <pre>
     * 获取access_token, 不强制刷新access_token
     * 详情请见：{@link http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html}
     * </pre>
     * @return
     * @throws WxErrorException
     */
    String getAccessToken() throws WxErrorException;

    /**
     * <pre>
     * 获取access_token，本方法线程安全
     * 且在多线程同时刷新时只刷新一次，避免超出2000次/日的调用次数上限
     * 另：本service的所有方法都会在access_token过期是调用此方法
     * 程序员在非必要情况下尽量不要主动调用此方法
     * 详情请见: {@link http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html}
     * </pre>
     *
     * @param forceRefresh
     *            强制刷新
     * @return
     * @throws WxErrorException
     */
    String getAccessToken(boolean forceRefresh) throws WxErrorException;

    /**
     * <pre>
     * 获取用户个人信息
     * 详情请见：{@link http://mp.weixin.qq.com/wiki/1/8a5ce6257f1d3b2afb20f83e72b72ce9.html}
     * </pre>
     * @param openid
     * @param lang  返回结果的语言版本  {@link WxConsts}
     * @return
     * @throws WxErrorException
     */
    WxUserList.WxUser getUserInfoByOpenId(WxUserList.WxUser.WxUserGet userGet) throws WxErrorException;

    /**
     * <pre>
     * 获取OAuth2.0认证的凭证 access_token
     * 这个access_token跟全局的access_token不同，可以到官方文档查阅
     * {@link http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html}
     * </pre>
     * @param code
     * 				oauth2buildAuthorizationUrl()重定向后会携带code
     * @return
     * @throws WxErrorException
     */
    MiniJsCode2SessionResult jsCode2SessionResult(String code) throws WxErrorException;

    /**
     * <pre>
     * 刷新access_token（如果需要）
     * 由于access_token拥有较短的有效期，当access_token超时后，可以使用refresh_token进行刷新，
     * refresh_token拥有较长的有效期（7天、30天、60天、90天），当refresh_token失效的后，需要用户重新授权
     *
     * 详情请见：{@link http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html}
     * </pre>
     * @param refresh_token 填写通过access_token获取到的refresh_token参数
     * @return
     * @throws WxErrorException
     */
    WxOAuth2AccessTokenResult oauth2ToGetRefreshAccessToken(String refresh_token) throws WxErrorException;

    /**
     * <pre>
     * 拉取用户信息(需scope为 snsapi_userinfo)
     * 如果网页授权作用域为snsapi_userinfo，则此时开发者可以通过access_token和openid拉取用户信息了。
     *
     * 详情请见：{@link http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html}
     *
     * </pre>
     * @param userGet
     * @return
     * @throws WxErrorException
     */
    WxUserList.WxUser oauth2ToGetUserInfo(String access_token, WxUserList.WxUser.WxUserGet userGet) throws WxErrorException;

    /**
     * <pre>
     * 检验授权凭证（access_token）是否有效
     *
     * 详情请见：{@link http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html}
     * </pre>
     * @param access_token
     * @param openid
     * @return WxError 若errcode=0，有效；反之，无效。
     * @throws WxErrorException
     */
    WxError oauth2CheckAccessToken(String access_token, String openid) throws WxErrorException;

    /**
     * 获取小程序码  适用于需要的码数量较少的业务场景
     * @param path 不能为空，最大长度 128 字节
     * @param width 二维码的宽度
     * @param auto_color 自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调
     * @param line_color auth_color 为 false 时生效，使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"},十进制表示
     * 通过该接口生成的小程序码，永久有效，数量限制见文末说明，请谨慎使用。用户扫描该码进入小程序后，将直接进入 path 对应的页面。
     * */
    String getwxacode(String path,String width,boolean auto_color,Object line_color)throws WxErrorException;

    /***
     * 获取小程序二维码 适用于需要的码数量较少的业务场景
     * @param path 不能为空，最大长度 128 字节
     * @param width 二维码的宽度
     * 通过该接口生成的小程序二维码，永久有效，数量限制见文末说明，请谨慎使用。用户扫描该码进入小程序后，将直接进入 path 对应的页面。
     */
    String createwxaqrcode(String path,String width)throws WxErrorException;


    /**
     * 当本Service没有实现某个API的时候，可以用这个，针对所有微信API中的GET请求
     *
     * @param url
     * @param params
     * @return
     * @throws WxErrorException
     */
    String get(String url, Map<String, String> params) throws WxErrorException;

    /**
     * 当本Service没有实现某个API的时候，可以用这个，针对所有微信API中的POST请求
     *
     * @param url
     * @param params
     * @return
     * @throws WxErrorException
     */
    String post(String url, String params) throws WxErrorException;

    /**
     * <pre>
     * Service没有实现某个API的时候，可以用这个，
     * 比{@link #get}和{@link #post}方法更灵活，可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
     * </pre>
     *
     * @param executor
     * @param uri
     * @param data
     * @param <T>
     * @param <E>
     * @return
     * @throws WxErrorException
     */
    <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException;
}
